package com.shop.trade.api.service.impl;

import com.shop.common.model.PayCallMdel;
import com.shop.common.model.ServiceBean;
import com.shop.common.model.param.trade.OrderBaseInput;
import com.shop.common.model.param.trade.OrderLogInput;
import com.shop.common.model.param.trade.OrderPayInput;
import com.shop.common.model.param.user.MessageInput;
import com.shop.common.model.param.user.UserPayInput;
import com.shop.common.model.param.user.UserPayLogInput;
import com.shop.common.model.result.trade.OrderBaseOutput;
import com.shop.common.model.result.trade.OrderPayOutput;
import com.shop.common.model.result.user.UserBaseOutput;
import com.shop.common.model.result.user.UserPayOutput;
import com.shop.common.tmpl.BaseService;
import com.shop.common.util.DateUtil;
import com.shop.common.util.SmsContent;
import com.shop.common.util.state.*;
import com.shop.trade.api.model.StatisModel;
import com.shop.trade.api.service.IOrderSvc;
import com.shop.trade.api.service.IPaySvc;
import com.shop.trade.atom.atomsvc.IOrderAtomSvc;
import com.shop.trade.atom.atomsvc.IOrderLogAtomSvc;
import com.shop.trade.atom.atomsvc.IPayAtomSvc;
import com.shop.trade.feign.item.IItemAtomFeignClientSvc;
import com.shop.trade.feign.user.IUserAtomFeignClientSvc;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description:
 *
 * @author zhoulk
 * @date: 2019年04月14日  12:22
 */
@Service
public class PaySvc extends BaseService implements IPaySvc {

    private static final Logger logger = LoggerFactory.getLogger(PaySvc.class);

    @Autowired
    IPayAtomSvc iPayAtomSvc;
    @Autowired
    IOrderAtomSvc iOrderAtomSvc;
    @Autowired
    IOrderSvc iOrderSvc;
    @Autowired
    IItemAtomFeignClientSvc iItemAtomFeignClientSvc;
    @Autowired
    IUserAtomFeignClientSvc iUserAtomFeignClientSvc;
    @Autowired
    IOrderLogAtomSvc iOrderLogAtomSvc;

    @Override
    public ServiceBean<Integer> addPayOrder(OrderPayInput orderPayInput) {
        return null;
    }

    @Override
    public ServiceBean<OrderPayOutput> qryPayOrder(OrderPayInput orderPayInput) {
        return null;
    }

    @Override
    public ServiceBean<Integer> modPayOrder(OrderPayInput orderPayInput) {
        return null;
    }

    @Override
    public ServiceBean<Integer> delPayOrder(List<Integer> ids) {
        return null;
    }

    @Override
    public ServiceBean<List<OrderPayOutput>> qryPayOrders4P(OrderPayInput inputBean) {
        return iPayAtomSvc.selectOrderPayList(inputBean);
    }

    @Override
    public ServiceBean<Map<String, BigDecimal>> qryStatis(OrderPayInput input) {
        input.setType(0);
        List<OrderPayOutput> outlist = iPayAtomSvc.selectOrderPayList(input).getData();
        input.setType(1);
        List<OrderPayOutput> inlist = iPayAtomSvc.selectOrderPayList(input).getData();
        BigDecimal outPrice = new BigDecimal(0);
        BigDecimal inPrice = new BigDecimal(0);
        if (outlist != null && !outlist.isEmpty()) {
            for (OrderPayOutput orderPayOutput : outlist) {
                outPrice = outPrice.add(orderPayOutput.getPayPrice().add(orderPayOutput.getBalance()));
            }
        }
        if (inlist != null && !inlist.isEmpty()) {
            for (OrderPayOutput orderPayOutput : inlist) {
                inPrice = outPrice.add(orderPayOutput.getPayPrice().add(orderPayOutput.getBalance()));
            }
        }
        Map<String, BigDecimal> map = new HashMap<>();
        map.put("outPrice", outPrice);
        map.put("inPrice", inPrice);
        return resultData(map);
    }

    @Override
    public List<StatisModel> qryStatisList(StatisModel statisModel) {
        return iPayAtomSvc.qryStatis(statisModel);
    }

    @Override
    public ServiceBean<String> payValidate(Integer orderId, Boolean isBalance) {
        ServiceBean<OrderBaseOutput> serviceBean = iOrderSvc.validateOrder(orderId, OrderState.WAITPAY.value());
        if (serviceBean.isFaild()) {
            if (serviceBean.getCode().intValue() == 400) {
                OrderBaseInput orderBaseInput = new OrderBaseInput();
                orderBaseInput.setId(orderId);
                orderBaseInput.setOrderStatus(OrderState.BUYERCANCEL.value());
                orderBaseInput.setComment(serviceBean.getMsg());
                iOrderAtomSvc.updateOrderBase(orderBaseInput);
            }
            return resultFailed(serviceBean.getMsg());
        }
        OrderBaseOutput orderBaseOutput = serviceBean.getData();

        OrderPayInput orderPayInput = new OrderPayInput();
        orderPayInput.setOrderId(orderBaseOutput.getId());
        ServiceBean<OrderPayOutput> orderPayOutputServiceBean = iPayAtomSvc.qryOrderPay(orderPayInput);
        if (orderPayOutputServiceBean.isSuccess()) {
            orderPayInput.setId(orderPayOutputServiceBean.getData().getId());
            orderPayInput.setPayStatus(2);
            orderPayInput.setCancelTime(DateUtil.newNowDate());
            iPayAtomSvc.updateOrderPay(orderPayInput);
            orderPayInput = new OrderPayInput();
        }
        Date now = DateUtil.newNowDate();
        BigDecimal transPrice = orderBaseOutput.getTransPrice().add(orderBaseOutput.getPostage());
        orderPayInput.setOrderId(orderBaseOutput.getId());
        orderPayInput.setBuyerId(orderBaseOutput.getBuyerId());
        orderPayInput.setMchtId(orderBaseOutput.getMchtId());
        orderPayInput.setPayStatus(PayState.WAIT.value());
        orderPayInput.setComment("订单支付");
        orderPayInput.setCreateTime(now);
        orderPayInput.setDataStatus(DataStatus.USE.value());
        orderPayInput.setType(0);

        if (isBalance) {//启用余额支付
            UserPayOutput userPayOutput = iUserAtomFeignClientSvc.qryUserPayByUserId(orderBaseOutput.getBuyerId());
            if (userPayOutput.getBalance().compareTo(transPrice) == -1) {
                orderPayInput.setPayPrice(transPrice.subtract(userPayOutput.getBalance()));
                orderPayInput.setBalance(userPayOutput.getBalance());
                orderPayInput.setPayType(3);
            } else {//如果用户余额大于订单支付价格，则直接使用余额进行支付
                orderPayInput.setPayPrice(new BigDecimal(0));
                orderPayInput.setBalance(transPrice);
                orderPayInput.setPayStatus(PayState.PAID.value());
                orderPayInput.setPayTime(now);
                orderPayInput.setPayType(2);
                ServiceBean<Integer> result = iPayAtomSvc.insertOrderPay(orderPayInput);
                //修改订单状态
                orderBaseOutput.setPayPrice(orderPayInput.getPayPrice());
                orderBaseOutput.setBalance(orderPayInput.getBalance());
                orderBaseOutput.setDataStatus(OrderState.PAID.value());
                orderBaseOutput.setPayType(2);
                orderBaseOutput.setPayTime(now);
                iOrderAtomSvc.updateOrderBase(orderBaseOutput);
                //记录订单日志
                OrderLogInput orderLogInput = OrderLogInput.newOrderLogInput(orderBaseOutput.getId(), OrderLogType.PAY.value(), 1,
                        orderBaseOutput.getOrderStatus(), OrderState.PAID.value(), orderBaseOutput.getBuyerId(),
                        orderBaseOutput.getMchtId(), "订单支付");//订单日志
                iOrderLogAtomSvc.addOrderLog(orderLogInput);

                sendMsg(orderBaseOutput.getMchtId(),"订单：+"+orderBaseOutput.getId()+"已支付",SmsContent.TMPL_1);

                /**
                 * 修改账户信息
                 **/
                UserPayInput userPayInput = new UserPayInput();
                userPayInput.setId(userPayOutput.getId());
                userPayInput.setBalance(userPayOutput.getBalance().subtract(orderPayInput.getBalance()));
                userPayInput.setModifyTime(DateUtil.newNowDate());
                iUserAtomFeignClientSvc.modUserPay(userPayInput);

                /**
                 * 记录用户余额变动日志
                 **/
                UserPayLogInput userPayLogInput = UserPayLogInput.newUserPayLog(orderBaseOutput.getBuyerId(), orderPayInput.getBalance(),
                        userPayOutput.getBalance(), 2, "订单支付扣除余额");
                userPayLogInput.setOrderId(orderBaseOutput.getId());
                userPayLogInput.setPayId(result.getData());
                iUserAtomFeignClientSvc.addUserPayLog(userPayLogInput);
                ServiceBean<String> res = new ServiceBean<>();
                res.setData(transPrice.toString());
                res.setMsg("paid");
                return res;
            }
        } else {
            orderPayInput.setPayPrice(transPrice);
            orderPayInput.setBalance(new BigDecimal(0));
            orderPayInput.setPayType(1);
        }
        ServiceBean<Integer> result = iPayAtomSvc.insertOrderPay(orderPayInput);
        return resultData(result.getData());
    }

    @Override
    public ServiceBean<OrderBaseOutput> payResultValidate(PayCallMdel payCallMdel, Integer userId) {
        Integer payId = Integer.valueOf(payCallMdel.getOut_trade_no());
        BigDecimal account = new BigDecimal(payCallMdel.getTotal_amount());
        Date date = DateUtil.newNowDate();
        String tradeId = payCallMdel.getTrade_no();

        OrderPayInput orderPayInput = new OrderPayInput();
        orderPayInput.setOutPayId(tradeId);
        ServiceBean<OrderPayOutput> payOutputServiceBean = iPayAtomSvc.qryOrderPay(orderPayInput);
        if (payOutputServiceBean.isSuccess()) {
            return resultFailed("success");
        }
        orderPayInput = new OrderPayInput();
        orderPayInput.setId(payId);
        payOutputServiceBean = iPayAtomSvc.qryOrderPay(orderPayInput);
        if (payOutputServiceBean.isFaild()) {
            return resultFailed("支付异常");
        }
        OrderPayOutput orderPayOutput = payOutputServiceBean.getData();
        ServiceBean<OrderBaseOutput> serviceBean = iOrderSvc.validateOrder(orderPayOutput.getOrderId(), OrderState.WAITPAY.value());
        OrderBaseOutput orderBaseOutput = serviceBean.getData();
        if (serviceBean.isFaild()) {
            orderPayOutput.setOutPayId(tradeId);
            refund(1008011, account, userId, orderPayOutput);
            return resultFailed(serviceBean.getMsg());
        }
        if (account.compareTo(orderPayOutput.getPayPrice()) != 0) {
            orderPayOutput.setOutPayId(tradeId);
            refund(1008011, account, userId, orderPayOutput);
            return resultFailed("支付金额异常");
        }
        // 修改支付单状态
        orderPayInput.setId(orderPayOutput.getId());
        orderPayInput.setPayStatus(PayState.PAID.value());
        orderPayInput.setPayTime(date);
        orderPayInput.setOutPayId(tradeId);
        iPayAtomSvc.updateOrderPay(orderPayInput);

        //修改订单状态
        OrderBaseInput orderBaseInput = new OrderBaseInput();
        orderBaseInput.setId(orderPayOutput.getOrderId());
        orderBaseInput.setPayPrice(orderPayOutput.getPayPrice());
        orderBaseInput.setBalance(orderPayOutput.getBalance());
        orderBaseInput.setPayTime(date);
        orderBaseInput.setPayType(orderPayInput.getPayType());
        orderBaseInput.setOrderStatus(OrderState.PAID.value());
        ServiceBean<Integer> sb = iOrderSvc.modOrder(orderBaseInput);

        //记录订单日志
        OrderLogInput orderLogInput = OrderLogInput.newOrderLogInput(orderBaseOutput.getId(), OrderLogType.PAY.value(), 1,
                orderBaseOutput.getOrderStatus(), OrderState.PAID.value(), orderBaseOutput.getBuyerId(), orderBaseOutput.getMchtId(), "订单支付");//订单日志
        iOrderLogAtomSvc.addOrderLog(orderLogInput);

        if (orderPayOutput.getBalance().doubleValue() > 0) {
            /**
             * 更新账户信息
             **/
            UserPayOutput userPayOutput = iUserAtomFeignClientSvc.qryUserPayByUserId(userId);
            UserPayInput userPayInput = new UserPayInput();
            userPayInput.setId(userPayOutput.getId());
            userPayInput.setBalance(userPayOutput.getBalance().subtract(orderPayOutput.getBalance()));
            userPayInput.setModifyTime(DateUtil.newNowDate());
            iUserAtomFeignClientSvc.modUserPay(userPayInput);

            /**
             * 记录用户余额变动日志
             **/
            UserPayLogInput userPayLogInput = UserPayLogInput.newUserPayLog(userId, orderPayOutput.getBalance(), userPayOutput.getBalance(),
                    2, "订单支付扣除余额");
            userPayLogInput.setOrderId(orderBaseOutput.getId());
            userPayLogInput.setPayId(orderPayOutput.getId());
            iUserAtomFeignClientSvc.addUserPayLog(userPayLogInput);
        }

        if (sb.isSuccess()) {
            return resultData(orderBaseOutput);
        } else {
            return resultFailed(sb.getMsg());
        }
    }

    @Override
    public ServiceBean<OrderBaseOutput> payResultValidate2(PayCallMdel payCallMdel, Integer userId) {
        String tradeId = payCallMdel.getTrade_no();
        Integer payId = Integer.valueOf(payCallMdel.getOut_trade_no());
        OrderPayInput orderPayInput = new OrderPayInput();
        orderPayInput.setOutPayId(tradeId);
        ServiceBean<OrderPayOutput> payOutputServiceBean = iPayAtomSvc.qryOrderPay(orderPayInput);
        if (payOutputServiceBean.isSuccess()) {
            return resultFailed("success");
        }
        orderPayInput = new OrderPayInput();
        orderPayInput.setId(payId);
        payOutputServiceBean = iPayAtomSvc.qryOrderPay(orderPayInput);
        OrderPayOutput orderPayOutput = payOutputServiceBean.getData();
        if (orderPayOutput.getType().intValue()==2){
            /**
             * 更新账户积分信息
             **/
            UserPayOutput userPayOutput = iUserAtomFeignClientSvc.qryUserPayByUserId(userId);
            UserPayInput userPayInput = new UserPayInput();
            userPayInput.setId(userPayOutput.getId());
            userPayInput.setIntegral(userPayOutput.getIntegral()+orderPayOutput.getPayPrice().intValue()*10);
            userPayInput.setModifyTime(DateUtil.newNowDate());
            iUserAtomFeignClientSvc.modUserPay(userPayInput);
            UserPayLogInput userPayLogInput = UserPayLogInput.newUserPayLog(userId, orderPayOutput.getPayPrice().intValue()*10,userPayOutput.getIntegral(),
                    1, "用户充值积分");
            userPayLogInput.setPayId(orderPayOutput.getId());
            iUserAtomFeignClientSvc.addUserPayLog(userPayLogInput);
        }
        // 修改支付单状态
        orderPayInput.setId(orderPayOutput.getId());
        orderPayInput.setPayStatus(PayState.PAID.value());
        orderPayInput.setPayTime(DateUtil.newNowDate());
        orderPayInput.setOutPayId(tradeId);
        iPayAtomSvc.updateOrderPay(orderPayInput);
        return resultSuccess();
    }

    private boolean refund(Integer mchtId, BigDecimal account, Integer userId, OrderPayOutput orderPayOutput) {
        UserPayOutput userPayOutput = iUserAtomFeignClientSvc.qryUserPayByUserId(userId);
        BigDecimal balance = account;
        /**
         * 创建充值账单
         **/
        OrderPayInput orderPayInput = new OrderPayInput();
        orderPayInput.setId(orderPayOutput.getId());
        orderPayInput.setOutPayId(orderPayOutput.getOutPayId());
        orderPayInput.setOrderId(0);
        orderPayInput.setBalance(new BigDecimal(0));
        orderPayInput.setPayPrice(account);
        orderPayInput.setBuyerId(userId);
        orderPayInput.setMchtId(mchtId);
        orderPayInput.setPayType(PayType.RECHARGE.value());
        orderPayInput.setType(2);
        orderPayInput.setPayStatus(PayState.PAID.value());
        orderPayInput.setComment("订单支付异常，支付金额充值为余额");
        orderPayInput.setPayTime(DateUtil.newNowDate());
        orderPayInput.setDataStatus(DataStatus.USE.value());
        iPayAtomSvc.updateOrderPay(orderPayInput);
        /**
         * 更新账户信息
         **/
        UserPayInput userPayInput = new UserPayInput();
        userPayInput.setId(userPayOutput.getId());
        userPayInput.setBalance(balance.add(userPayOutput.getBalance()));
        userPayInput.setModifyTime(DateUtil.newNowDate());
        ServiceBean<String> serviceBean = iUserAtomFeignClientSvc.modUserPay(userPayInput);

        /**
         * 记录用户余额变动日志
         **/
        UserPayLogInput userPayLogInput = UserPayLogInput.newUserPayLog(userId, balance, userPayOutput.getBalance(), 1, "订单支付失败，充值到余额");
        userPayLogInput.setOrderId(0);
        userPayLogInput.setPayId(orderPayInput.getId());
        iUserAtomFeignClientSvc.addUserPayLog(userPayLogInput);
        return serviceBean.isSuccess();
    }

    private boolean sendMsg(Integer userId, String content, SmsContent smsContent){
        UserBaseOutput userBaseOutput = iUserAtomFeignClientSvc.qryUserBaseByUserId(userId);
        MessageInput messageInput = new MessageInput();
        messageInput.setSendId(1008612);
        messageInput.setAcceptId(userId);
        messageInput.setAccptPhone(userBaseOutput.getPhone());
        messageInput.setMsgTitle("订单处理");
        messageInput.setMsgContent(content);
        messageInput.setMsgType(1);
        messageInput.setMsgStatus(0);
        messageInput.setSendTime(DateUtil.newNowDate());
        messageInput.setAccptType(1);
        messageInput.setAccptEmail(userBaseOutput.getEmail());
        messageInput.setCreateTime(DateUtil.newNowDate());
        messageInput.setDataState(DataStatus.USE.value());
        messageInput.setAccptTip(smsContent.value());
        iUserAtomFeignClientSvc.sendMsg(messageInput);
        return true;
    }
}
